#ifndef MATRIXEDGEITERATOR_H_
#define MATRIXEDGEITERATOR_H_

#include "graph_support/GraphSupport.h"

namespace GRAPH_SUPPORT_NS
{
namespace impls
{
namespace matrix
{

template< typename EdgeT >
class MatrixEdgeIterator
{
private:
	typedef EdgeT GrEdge;
	typedef GrEdge * GrEdgePtr;

public:
	MatrixEdgeIterator( GrEdgePtr * matrBeg, GrEdgePtr * matrCur, GrEdgePtr * matrEnd )
		: matrBeg( matrBeg )
		, matrCur( matrCur )
		, matrEnd( matrEnd )
	{
		iterThoNextEdge();
	}

	MatrixEdgeIterator & operator ++ ()
	{
		assert( matrCur < matrEnd );
		matrCur++;
		iterThoNextEdge();
		return * this;
	}

public:
	typedef int difference_type;
	typedef GrEdgePtr value_type;
	typedef GrEdgePtr * pointer;
	typedef GrEdgePtr & reference;
	typedef std::forward_iterator_tag iterator_category;

public:
	// TODO: review != operators
	bool operator == ( const MatrixEdgeIterator & that ) const
	{
		return matrBeg == that.matrBeg && matrCur == that.matrCur && matrEnd == that.matrEnd;
	}

	bool operator != ( const MatrixEdgeIterator & that ) const
	{
		return ! ( * this == that );
	}

	GrEdgePtr operator * ()
	{
		return * ( this->operator -> () );
	}

	GrEdgePtr * operator -> ()
	{
		assert( matrCur != matrEnd );
		return matrCur == matrEnd ? NULL : matrCur;
	}

private:
	void iterThoNextEdge()
	{
		while ( matrCur < matrEnd && !*matrCur )
		{
			matrCur++;
		}
	}

private:
	GrEdgePtr * matrBeg;
	GrEdgePtr * matrCur;
	GrEdgePtr * matrEnd;
};

}
}
}

#endif /* MATRIXEDGEITERATOR_H_ */
